Skip to content

S07-02 数据可视化-Canvas-API

[TOC]

API-Canvas

索引

canvas

  • <canvas>with height,被用来通过 JS(Canvas API 或 WebGL API)绘制图形及图形动画的元素。
  • el.getContext()(contextType, contextAttributes?),返回canvas的上下文,如果上下文没有定义则返回null
  • el.toDataURL()(type?, quality?),将 Canvas 转换为 Base64 编码的图像。

设置

  • ctx.fillStylecolor| gradient | pattern默认:#000,设置或获取 Canvas 填充颜色或样式
  • ctx.strokeStylecolor| gradient | pattern默认:#000,描边颜色
  • ctx.globalAlphanumber默认:1.0,0~1的数值,值越小透明度越高,设置或获取 Canvas 的全局透明度。
  • ctx.createLinearGradient()(x0, y0, x1, y1),创建一个沿着参数坐标指定的线的线性渐变
  • ctx.createRadialGradient()(x0, y0, r0, x1, y1, r1),创建一个沿着参数坐标指定的线的放射性渐变
  • gradient.addColorStop()(offset, color),用于在渐变中设置颜色停靠点。gradient是通过上述2个方法创建出来的CanvasGradient对象。
  • ctx.createPattern()(image, repetition),用于创建一个图案。
  • ctx.lineWidthnumber默认:1,设置线条宽度。不带px单位
  • ctx.lineCapbutt | round | square默认:butt,用于设置路径的端点样式。
  • ctx.lineJoinround | bevel | miter默认:bevel,控制路径连接处的形状。

路径

  • ctx.beginPath()(),开始一条新的路径的方法。每次调用 beginPath() 都会清除当前路径,使接下来的绘图操作不会连接到先前的路径上。
  • ctx.closePath()(),用于关闭当前路径的方法。将路径的最后一部分连接回到起始点,形成一个闭合的路径。
  • ctx.stroke()(),通过线条来绘制图形轮廓/描边(针对当前路径)。
  • ctx.fill()(),通过填充路径的内容区域生成实心的图形(针对当前路径)。
  • ctx.moveTo()(x, y),将当前路径的起始点移动到指定的起始点坐标点
  • ctx.lineTo()(x, y),通过连接当前路径的末端点和指定的 (x, y) 坐标来绘制一条直线。
  • ctx.rect()(x, y, width, height),创建一个矩形路径。
  • ctx.arc()(x, y, radius, startAngle, endAngle, anticlockwise?),绘制一段圆弧或圆的方法。0表示3点钟方向。
  • ctx.ellipsis()(x, y, radiusX, radiusY, rotation, startAngle, endAngle, anticlockwise?),添加一个椭圆路径。
  • ctx.bezierCurveTo()(cp1x, cp1y, cp2x, cp2y, x, y),添加一个 3 次贝赛尔曲线路径。起始点是当前路径的最后一个点,绘制贝赛尔曲线前,可以通过调用 moveTo() 进行修改。

绘制矩形

  • ctx.fillRect()(x, y, width, height),绘制填充矩形
  • ctx.strokeRect()(x, y, width, height),绘制一个描边矩形
  • ctx.clearRect()(x, y, width, height), 清除指定矩形区域,让清除部分完全透明。

绘制文本

  • ctx.fontfont-style? font-variant? font-weight? font-size line-height? font-family默认:10px sans-serif,设置文本的字体样式。
  • ctx.textAlignstart | end | left | right | center默认:start,文本对齐选项。
  • ctx.textBaselinetop | hanging | middle | alphabetic | ideographic | bottom默认:alphabetic,基线对齐选项。
  • ctx.fillText()(text, x, y, maxWidth?),绘制填充文本。
  • ctx.strokeText()(text, x, y, maxWidth?),绘制描边文本。

绘制图片

  • ctx.drawImage()(image, x, y)版本 1: 绘制图像到画布(不缩放、不裁剪)
  • ctx.drawImage()(image, x, y, width, height)版本 2: 绘制图像并缩放
  • ctx.drawImage()(image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight)版本 3: 从图像中裁剪出指定的区域,并将其绘制到画布。

形变

  • 保存和恢复绘画状态
  • ctx.save()(),将当前的绘图状态保存到状态栈中。
  • ctx.restore()(),从状态栈中恢复canvas的当前绘画状态。
  • ctx.translate()(x, y),平移整个画布上的所有内容。
  • ctx.rotate()(angle),用于旋转绘图上下文的坐标系。所有后续绘制的内容都将基于旋转后的坐标系进行。
  • ctx.scale()(x, y),用于缩放绘图上下文的整个坐标系。用来增减图形在canvas中的像素数目。会影响到所有后续绘制的图形。

动画

  • setInterval()(callback, interval?, arg1?, arg2?, ...),按照指定的时间间隔重复执行一个函数,直到被清除或页面关闭。
  • setTimeout()(callback, delay, arg1, arg2, ...),在指定的延迟时间后执行一个函数,只执行一次。
  • requestAnimationFrame()(callback),一种浏览器提供的机制,用于在浏览器的下一次重绘之前执行一个函数,它被广泛应用于动画的实现。

canvas

canvas

<canvas>with height,被用来通过 JS(Canvas API 或 WebGL API)绘制图形及图形动画的元素。

  • widthnumber默认:300,画布的宽度

  • heightnumber默认:150,画布的高度

  • html
    <canvas width="300" height="150"></canvas>

getContext()

el.getContext()(contextType, contextAttributes?),返回canvas的上下文,如果上下文没有定义则返回null 。

  • contextType'2d' | 'webgl' | 'webgl2' | 'bitmaprenderer'默认:'2d',指定渲染上下文类型

    • 2d常用,建立一个 CanvasRenderingContext2D 二维渲染上下文
    • webgl:创建一个 WebGLRenderingContext 三维渲染上下文对象
    • webgl2:创建一个 WebGL2RenderingContext 三维渲染上下文对象
    • bitmaprenderer:创建一个只提供将 canvas 内容替换为指定ImageBitmap功能的ImageBitmapRenderingContext
  • contextAttributes?{antialias, depth, stencil, alpha, premultipliedAlpha, preserveDrawingBuffer, failIfMajorPerformanceCaveat}默认:{},可以在创建渲染上下文的时候设置多个属性【更多

    • antialiasboolean默认:true,是否启用抗锯齿。true 表示启用抗锯齿。
    • depthboolean默认:true,是否启用深度缓冲。true 表示启用深度缓冲。
    • stencilboolean默认:false,是否启用模板缓冲。true 表示启用模板缓冲。
    • alphaboolean默认:false,是否启用透明度。true 表示启用。
    • premultipliedAlphaboolean默认:true,是否将 alpha 通道预乘到颜色通道中。
    • preserveDrawingBufferboolean默认:false,是否保留绘制缓冲区。该属性常用于保存绘制内容进行后期处理。
    • failIfMajorPerformanceCaveatboolean默认:false,是否在性能较差时放弃创建上下文。
  • 返回:

  • ctxCanvasRenderingContext2D | WebGLRenderingContext | WebGL2RenderingContext | ImageBitmapRenderingContext | null,返回指定类型的渲染上下文,如果上下文没有定义则返回null 。

  • js
    // 获取 2D 上下文
    const canvas = document.getElementById('myCanvas');
    const ctx = canvas.getContext('2d');
    
    // 获取 WebGL 上下文
    const gl = canvas.getContext('webgl', { antialias: true, depth: true });

toDataURL()

el.toDataURL()(type?, quality?),将 Canvas 转换为 Base64 编码的图像。

  • type?MIME默认:image/png,图片格式。MIME类型

  • quality?number默认:0.92,从 0 到 1 的区间内选择图片的质量。只在 type'image/jpeg''image/webp' 时才有效。

  • 返回:

  • dataURLstring,包含 data URI 的字符串。如:"data:image/png;base64,xxxx..."

  • js
    const canvas = document.getElementById('myCanvas');
    const dataURL = canvas.toDataURL('image/png');
    
    // 显示 Base64 图像
    const img = new Image();
    img.src = dataURL;
    document.body.appendChild(img);  // 将图像添加到页面上显示
    
    // 创建下载链接
    const link = document.createElement('a');
    link.href = dataURL;
    link.download = 'canvas-image.png';  // 设置下载的文件名
    link.click();  // 模拟点击下载

设置

颜色

fillStyle

ctx.fillStylecolor| gradient | pattern默认:#000,设置或获取 Canvas 填充颜色或样式

  • js
    // 颜色值
    ctx.fillStyle = 'red';
    ctx.fillRect(50, 50, 150, 100);
    
    // 线性渐变
    const gradient = ctx.createLinearGradient(0, 0, canvas.width, 0);
    gradient.addColorStop(0, 'red');   // 起始点为红色
    gradient.addColorStop(1, 'blue');  // 结束点为蓝色
    ctx.fillStyle = gradient;
    ctx.fillRect(50, 50, 150, 100);
    
    // 放射性渐变
    const gradient2 = ctx.createRadialGradient(200, 150, 20, 200, 150, 150);
    gradient2.addColorStop(0, 'yellow');   // 中心点为黄色
    gradient2.addColorStop(1, 'green');    // 外圈为绿色
    ctx.fillStyle = gradient2;
    
    ctx.beginPath();
    ctx.arc(200, 150, 150, 0, Math.PI * 2, false);
    ctx.fill();
    
    // 图案
    const img = new Image();
    img.src = 'https://www.example.com/path/to/your/image.jpg';  // 图像路径
    img.onload = function() {
        const pattern = ctx.createPattern(img, 'repeat');  // 图案以平铺方式重复
        ctx.fillStyle = pattern;
        ctx.fillRect(50, 50, 300, 200);
    };
    
    // 获取 fillStyle 的当前值
    const currentFillStyle = ctx.fillStyle;
    console.log(currentFillStyle);
strokeStyle

ctx.strokeStylecolor| gradient | pattern默认:#000,描边颜色

  • js
    // 示例如上
    
    // 颜色值
    // 线性渐变
    // 放射性渐变
    // 图案
    // 获取 fillStyle 的当前值

透明

globalAlpha

ctx.globalAlphanumber默认:1.0,0~1的数值,值越小透明度越高,设置或获取 Canvas 的全局透明度。

  • 注意: 高频率绘制大量图形时,过度使用全局透明度可能会影响性能

  • js
    const canvas = document.getElementById('myCanvas');
    const ctx = canvas.getContext('2d');
    
    // 设置全局透明度为 0.5(50% 透明)
    ctx.globalAlpha = 0.5;
    
    // 绘制一个半透明的矩形
    ctx.fillStyle = 'red';
    ctx.fillRect(50, 50, 200, 100);

渐变

createLinearGradient()

ctx.createLinearGradient()(x0, y0, x1, y1),创建一个沿着参数坐标指定的线的线性渐变

  • x0, y0number,渐变的起点坐标。不带px单位

  • x1, y1number,渐变的终点坐标。不带px单位

  • 返回:

  • gradientCanvasGradient,可以通过 addColorStop() 方法在渐变中添加颜色停靠点。

  • js
    // 创建一个线性渐变,从左上角(0, 0)到右下角(400, 400)
    var gradient = ctx.createLinearGradient(0, 0, 400, 400);
    
    // 定义渐变颜色的停靠点
    gradient.addColorStop(0, 'red');        // 从起点(0,0)开始为红色
    gradient.addColorStop(0.5, 'yellow');  // 在中间50%位置为黄色
    gradient.addColorStop(1, 'blue');      // 从终点(400, 400)为蓝色
    
    // 使用渐变填充矩形
    ctx.fillStyle = gradient;
createRadialGradient()

ctx.createRadialGradient()(x0, y0, r0, x1, y1, r1),创建一个沿着参数坐标指定的线的放射性渐变

  • x0, y0number,开始圆形的圆心。不带px单位

  • r0number,开始圆形的半径。不带px单位

  • x1, y1number,结束圆形的圆心。不带px单位

  • r1number,结束圆形的半径。不带px单位

  • 返回:

  • gradientCanvasGradient,可以通过 addColorStop() 方法在渐变中添加颜色停靠点。

  • js
    // 创建一个径向渐变,起始圆心为(200, 200),半径为50
    // 终止圆心为(200, 200),半径为200
    var gradient = ctx.createRadialGradient(200, 200, 50, 200, 200, 200);
    
    // 定义渐变颜色的停靠点
    gradient.addColorStop(0, 'red');       // 从起始圆心开始为红色
    gradient.addColorStop(0.5, 'yellow'); // 在中间50%位置为黄色
    gradient.addColorStop(1, 'blue');     // 在终止圆心位置为蓝色
    
    // 使用渐变填充矩形
    ctx.fillStyle = gradient;
addColorStop()

gradient.addColorStop()(offset, color),用于在渐变中设置颜色停靠点。gradient是通过上述2个方法创建出来的CanvasGradient对象。

  • offsetnumber,表示颜色停靠点的位置。介于0-1之间的数字,0表示渐变的起点,1表示渐变的终点

  • colorColor,要应用的颜色,可以是任意有效的 CSS 颜色值。

  • js
    // 创建一个线性渐变,从左上角(0, 0)到右下角(400, 400)
    var gradient = ctx.createLinearGradient(0, 0, 400, 400);
    
    // 定义渐变颜色的停靠点
    gradient.addColorStop(0, 'red');        // 从起点(0,0)开始为红色
    gradient.addColorStop(0.5, 'yellow');  // 在中间50%位置为黄色
    gradient.addColorStop(1, 'blue');      // 从终点(400, 400)为蓝色

图案

createPattern()

ctx.createPattern()(image, repetition),用于创建一个图案。

  • imageHTMLImageElement | HTMLCanvasElement | HTMLVideoElement | ImageBitmap,用作图案的图像,可以是以下几种类型:

    • HTMLImageElement <img>标签加载的图片
    • HTMLCanvasElement :一个已有图像内容的 <canvas> 元素
    • HTMLVideoElement :一个视频元素
    • ImageBitmap:用于提供更高效的图像处理
  • repetition'repeat' | 'repeat-x' | 'repeat-y' | 'no-repeat'默认:'repeat',指定如何重复图像。

  • 返回:

  • patternCanvasPattern,可用作 fillStylestrokeStyle 进行填充或描边。

  • js
            var canvas = document.getElementById('myCanvas');
            var ctx = canvas.getContext('2d');
          
            // 创建一个图像元素
            var img = new Image();
            img.src = 'https://www.example.com/your-image.png';  // 替换为你自己的图片链接
          
            img.onload = function() {
                // 创建图案
                var pattern = ctx.createPattern(img, 'repeat');  // 选择重复方式为 'repeat'
                
                // 将图案作为填充样式
                ctx.fillStyle = pattern;
          
                // 绘制一个填充图案的矩形
                ctx.fillRect(0, 0, canvas.width, canvas.height);
            };

线型

lineWidth

ctx.lineWidthnumber默认:1,设置线条宽度。不带px单位

  • js
    // 设置线条宽度为 5
    ctx.lineWidth = 5;
    
    ctx.beginPath();
    ctx.moveTo(50, 100);
    ctx.lineTo(450, 100);
    ctx.stroke();  // 绘制宽度为 5 的线条
lineCap

ctx.lineCapbutt | round | square默认:butt,用于设置路径的端点样式。

  • butt:平直的线条端点,不做任何修饰。

  • round:圆形的线条端点,端点会变成一个半圆形。

  • square:方形的线条端点,端点会延伸成一个正方形。

  • js
    // 设置线条宽度
    ctx.lineWidth = 20;
    
    // 设置端点为 'butt'(默认值)
    ctx.lineCap = 'butt';  
    
    ctx.beginPath();
    ctx.moveTo(50, 50);
    ctx.lineTo(450, 50);
    ctx.stroke();  // 绘制线条,端点是平的
lineJoin

ctx.lineJoinround | bevel | miter默认:miter,控制路径连接处的形状。

  • bevel:斜接连接。连接处形成一个斜切角。

  • round:圆形连接。连接处会形成一个圆形的角。

  • miter:尖角连接。连接处会根据角度形成一个尖锐的角(需要设置 miterLimit 来控制最大尖角长度)。

  • js
    // 设置线条宽度
    ctx.lineWidth = 20;
    
    // 设置连接样式为 'bevel'
    ctx.lineJoin = 'bevel';  
    
    ctx.beginPath();
    ctx.moveTo(50, 50);
    ctx.lineTo(150, 50);
    ctx.lineTo(100, 100);  // 三条线段形成连接点
    ctx.closePath();  // 关闭路径,形成闭合的形状
    ctx.stroke();  // 绘制线条

路径

开启闭合

beginPath()

ctx.beginPath()(),开始一条新的路径的方法。每次调用 beginPath() 都会清除当前路径,使接下来的绘图操作不会连接到先前的路径上。

  • js
    // 第一个矩形(之前的路径已经结束)
    ctx.beginPath();  // 开始新的路径
    ctx.rect(50, 50, 200, 100);  // 绘制一个矩形
    ctx.fillStyle = 'blue';
    ctx.fill();  // 填充矩形
    
    // 第二个矩形(开始新路径)
    ctx.beginPath();  // 开始一个新的路径
    ctx.rect(100, 200, 150, 75);  // 绘制另一个矩形
    ctx.fillStyle = 'green';
    ctx.fill();  // 填充第二个矩形
closePath()

ctx.closePath()(),用于关闭当前路径的方法。将路径的最后一部分连接回到起始点,形成一个闭合的路径。

  • js
    // 绘制一个矩形
    ctx.beginPath();  // 开始路径
    ctx.moveTo(50, 50);  // 起点
    ctx.lineTo(200, 50);  // 绘制到(200, 50)
    ctx.lineTo(200, 150); // 绘制到(200, 150)
    ctx.lineTo(50, 150);  // 绘制到(50, 150)
    ctx.closePath();  // 连接最后一点到起点,闭合路径
    ctx.stroke();  // 绘制矩形的边框

移动笔触

moveTo()

ctx.moveTo()(x, y),将当前路径的起始点移动到指定的起始点坐标点

  • x, ynumber,目标位置的横坐标、纵坐标。不带px单位

  • js
    ctx.beginPath();
    // 使用 moveTo() 将路径的起始点移动到 (50, 50)
    ctx.moveTo(50, 50);
    ctx.lineTo(200, 50);
    ctx.stroke();

绘制路径

stroke()

ctx.stroke()(),通过线条来绘制图形轮廓/描边(针对当前路径)。

  • js
    // 设置绘图样式
    ctx.strokeStyle = 'blue';  // 边框颜色
    ctx.lineWidth = 5;         // 线宽
    
    // 绘制一个矩形
    ctx.beginPath();           // 开始路径
    ctx.rect(50, 50, 200, 150); // 绘制矩形
    ctx.stroke();              // 绘制矩形的边框
fill()

ctx.fill()(),通过填充路径的内容区域生成实心的图形(针对当前路径)。

  • js
    // 设置填充样式
    ctx.fillStyle = 'yellow'; // 填充颜色
    
    // 绘制并填充矩形
    ctx.beginPath();           // 开始路径
    ctx.rect(50, 50, 200, 150); // 绘制矩形
    ctx.fill();                // 填充矩形的内部

直线

lineTo()

ctx.lineTo()(x, y),通过连接当前路径的末端点和指定的 (x, y) 坐标来绘制一条直线。

  • x, ynumber,目标位置的横坐标、纵坐标。不带px单位

  • js
    ctx.beginPath();
    ctx.moveTo(50, 50);
    // 使用 lineTo() 绘制一条从 (50, 50) 到 (200, 50) 的水平线
    ctx.lineTo(200, 50);
    ctx.stroke();

矩形

rect()

ctx.rect()(x, y, width, height),创建一个矩形路径。

  • x, ynumber,矩形的起点位置。不带px单位

  • width, heightnumber,矩形的宽度、高度。不带px单位

  • js
    // 设置填充颜色
    ctx.fillStyle = "blue";
    
    // 创建矩形路径
    ctx.beginPath();  // 开始路径
    ctx.rect(50, 50, 200, 100);  // 创建矩形路径
    ctx.fill();  // 填充矩形

圆形

arc()

ctx.arc()(x, y, radius, startAngle, endAngle, anticlockwise?),绘制一段圆弧或圆的路径。0表示3点钟方向。

  • x, ynumber,圆心点。不带px单位

  • radiusnumber,半径。不带px单位

  • startAngle, endAngle弧度,开始、结束角度。0表示3点钟方向。

  • anticlockwise?boolean默认:false,是否逆时针绘制圆弧。true: 逆时针,false: 顺时针。

  • js
    // 设置填充颜色
    ctx.fillStyle = "blue";
    
    // 绘制完整的圆
    ctx.beginPath(); // 开始路径
    ctx.arc(250, 250, 100, 0, 2 * Math.PI);  // 圆心(250, 250),半径100,角度从0到2π
    ctx.fill();  // 填充圆
ellipsis()

ctx.ellipsis()(x, y, radiusX, radiusY, rotation, startAngle, endAngle, anticlockwise?),添加一个椭圆路径。

  • x, ynumber,椭圆的圆心。

  • radiusX, radiusYnumber,椭圆的 x 轴和 y 轴半径。

  • rotation弧度默认:0,椭圆的旋转角度。

  • startAngle, endAngle弧度,绘制的起始点、结束点角度

  • anticlockwise?boolean默认:false,是否逆时针绘制圆弧。true: 逆时针,false: 顺时针。

  • js
    // 设置填充颜色
    ctx.fillStyle = "lightblue";
    
    // 绘制一个椭圆
    ctx.beginPath();
    // 圆心(250, 250),半径150和100,旋转0,绘制完整椭圆
    ctx.ellipse(250, 250, 150, 100, 0, 0, 2 * Math.PI); 
    ctx.fill(); // 填充椭圆

曲线

bezierCurveTo()

ctx.bezierCurveTo()(cp1x, cp1y, cp2x, cp2y, x, y),添加一个 3 次贝赛尔曲线路径。起始点是当前路径的最后一个点,绘制贝赛尔曲线前,可以通过调用 moveTo() 进行修改。

  • cp1x, cp1ynumber,第一个控制点。不带px单位

  • cp2x, cp2ynumber,第二个控制点。不带px单位

  • x, ynumber,第三个点是结束点。不带px单位

  • 注意: 起点和终点确定了曲线的方向和位置,而控制点决定了曲线的弯曲程度。

  • js
      // 开始路径
      ctx.beginPath()
      
      // 移动到起点 (50, 250)
      ctx.moveTo(50, 250)
      
      // 绘制贝塞尔曲线,控制点为 (150, 50) 和 (350, 450),终点为 (450, 250)
      ctx.bezierCurveTo(150, 50, 350, 450, 450, 250)
      
      // 绘制路径
      ctx.stroke()

绘制矩形

fillRect()

ctx.fillRect()(x, y, width, height),绘制填充矩形

  • x, ynumber,矩形起始点。不带px单位

  • width, heightnumber,矩形的宽度、高度。不带px单位

  • js
    // 设置填充颜色为红色
    ctx.fillStyle = "red";
    
    // 绘制一个填充矩形
    ctx.fillRect(50, 50, 200, 100);  // (x, y, width, height)

strokeRect()

ctx..strokeRect()(x, y, width, height),绘制一个描边矩形

  • x, ynumber,矩形起始点。不带px单位

  • width, heightnumber,矩形的宽度、高度。不带px单位

  • js
    // 设置描边颜色为红色
    ctx.strokeStyle = "red";
    
    // 绘制一个描边矩形
    ctx.strokeRect(50, 50, 200, 100);  // (x, y, width, height)

clearRect()

ctx.clearRect()(x, y, width, height), 清除指定矩形区域,让清除部分完全透明。

  • x, ynumber,矩形区域左上角的 x,y 坐标。

  • width, heightnumber,矩形区域的宽度和高度。

  • js
    // 绘制一个红色矩形
    ctx.fillStyle = 'red';
    ctx.fillRect(50, 50, 200, 100);
    
    // 清除矩形的一部分(从坐标 (50, 50) 开始,宽度 100,高度 50)
    ctx.clearRect(50, 50, 100, 50); // 清除矩形的上半部分
    
    // 重新绘制一个蓝色矩形
    ctx.fillStyle = 'blue';
    ctx.fillRect(150, 150, 200, 100);

绘制文本

font

ctx.fontfont-style? font-variant? font-weight? font-size line-height? font-family默认:10px sans-serif,设置文本的字体样式。

  • font-style?normal | italic | oblique,定义字体样式:普通,斜体,倾斜体。

  • font-variant?small-caps,用于设置字体变体,通常是小型大写字母(如:small-caps)。

  • font-weight?normal | bold | bolder | lighter | 100...900,设置字体的粗细,常见值包括:

  • font-sizepx | em | rem | pt,设置字体大小,常见单位包括:

  • line-height?number | % | px | em | rem,设置行高,可以是数字、百分比或单位。

  • font-family:设置字体的家族。

  • js
    // 设置斜体和粗体字体
    ctx.font = "italic bold 40px 'Times New Roman'";
    
    // 设置文本颜色
    ctx.fillStyle = "red";
    
    // 绘制文本
    ctx.fillText("Styled Text", 50, 100);

textAlign

ctx.textAlignstart | end | left | right | center默认:start,文本对齐选项。

  • start和left的区别: 有些语言书写顺序是从右到左,这时二者就有区别了。

  • js
    // 设置字体
    ctx.font = "30px Arial";
    
    // 设置不同的对齐方式
    ctx.textAlign = "start";   // 左对齐
    ctx.fillText("Start Align", 50, 50);
    
    ctx.textAlign = "center";  // 居中对齐
    ctx.fillText("Center Align", 250, 100);
    
    ctx.textAlign = "end";     // 右对齐
    ctx.fillText("End Align", 450, 150);

textBaseline

ctx.textBaselinetop | hanging | middle | alphabetic | ideographic | bottom默认:alphabetic,基线对齐选项。

  • js
    // 设置字体
    ctx.font = "30px Arial";
    
    // 设置不同的垂直对齐方式,并绘制文本
    ctx.textBaseline = "top";      // 基线在文本顶部
    ctx.fillText("Top Baseline", 50, 50);
    
    ctx.textBaseline = "hanging"; // 挂起基线
    ctx.fillText("Hanging Baseline", 50, 100);
    
    ctx.textBaseline = "middle";  // 中心基线
    ctx.fillText("Middle Baseline", 50, 150);
    
    ctx.textBaseline = "alphabetic"; // 字母基线(默认)
    ctx.fillText("Alphabetic Baseline", 50, 200);
    
    ctx.textBaseline = "ideographic"; // 适用于象形文字
    ctx.fillText("Ideographic Baseline", 50, 250);
    
    ctx.textBaseline = "bottom";   // 基线在文本底部
    ctx.fillText("Bottom Baseline", 50, 300);
  • image-20241127172621349

fillText()

ctx.fillText()(text, x, y, maxWidth?),绘制填充文本。

  • textstring,文本内容。

  • x, ynumber,文本起始点。x表示左侧边缘,y表示基线位置。

  • maxWidth?number,指定绘制文本时的最大宽度

  • js
    // 设置字体样式
    ctx.font = "30px Arial";
    ctx.fillStyle = "green";  // 设置填充颜色为绿色
    
    // 在坐标 (50, 100) 绘制文本,最大宽度为 150 像素
    ctx.fillText("This is a very long text", 50, 100, 150);

strokeText()

ctx.strokeText()(text, x, y, maxWidth?),绘制描边文本。

  • textstring,文本内容。

  • x, ynumber,文本起始点。x表示左侧边缘,y表示基线位置。

  • maxWidth?number,指定绘制文本时的最大宽度

  • js
    // 设置字体样式
    ctx.font = "30px Arial";
    ctx.lineWidth = 3;          // 设置线宽为 3
    ctx.strokeStyle = "blue";   // 设置轮廓颜色为蓝色
    
    // 绘制文本的轮廓,最大宽度为 150 像素
    ctx.strokeText("This is a long text", 50, 100, 150);

绘制图片

drawImage()

ctx.drawImage()(image, x, y)版本 1: 绘制图像到画布(不缩放、不裁剪)

  • imageImage | Canvas | Video,绘制到上下文的元素。允许任何的画布图像源。

  • x, ynumber,图像起始位置(左上角)在画布上的水平、垂直坐标。不带px单位。

  • js
    // 创建一个图像对象
    var img = new Image();
    img.src = 'https://www.example.com/your-image.jpg';  // 请替换成你自己的图片 URL
    
    img.onload = function() {
        // 当图像加载完成后,绘制图像
        ctx.drawImage(img, 50, 50);  // 将图像绘制到 (50, 50) 位置
    };

ctx.drawImage()(image, x, y, width, height)版本 2: 绘制图像并缩放

  • imageImage | Canvas | Video,绘制到上下文的元素。允许任何的画布图像源。

  • x, ynumber,图像起始位置(左上角)在画布上的水平、垂直坐标。不带px单位。

  • width, heightnumber,缩放图像到指定的宽度和高度。不带px单位。

  • js
    // 创建一个图像对象
    var img = new Image();
    img.src = 'https://www.example.com/your-image.jpg';  // 请替换成你自己的图片 URL
    
    img.onload = function() {
        // 绘制图像并缩放
        ctx.drawImage(img, 50, 50, 200, 150);  // 将图像绘制到 (50, 50) 位置,并缩放到 200x150
    };

ctx.drawImage()(image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight)版本 3: 从图像中裁剪出指定的区域,并将其绘制到画布。

  • imageImage | Canvas | Video,绘制到上下文的元素。允许任何的画布图像源。

  • sx, synumber,image裁剪区域的起始点坐标。不带px单位。

  • sWidth, sHeightnumber,image裁剪区域的宽度和高度。不带px单位。

  • dx, dynumber,目标画布上的左上角坐标。不带px单位。

  • dWidth, dHeightnumber,目标画布上绘制的宽高。不带px单位。

  • js
    // 创建一个图像对象
    var img = new Image();
    img.src = 'https://www.example.com/your-image.jpg';  // 请替换成你自己的图片 URL
    
    img.onload = function() {
        // 裁剪图像并绘制
        ctx.drawImage(img, 100, 100, 300, 200, 50, 50, 250, 150);
        // 从 (100, 100) 开始裁剪,裁剪出 300x200 的区域
        // 然后将裁剪的部分绘制到 (50, 50) 位置,缩放到 250x150
    };
    js
    /** 将视频的每帧绘制到画布上,实现视频播放的效果。 */
    function draw() {
        ctx.drawImage(video, 0, 0, 500, 500);  // 将视频帧绘制到画布上
        requestAnimationFrame(draw);  // 请求下一帧
    }
    draw();

形变

save()

ctx.save()(),将当前的绘图状态保存到状态栈中。

ctx.restore()(),从状态栈中恢复canvas的当前绘画状态。

  • js
    // 绘制第一个矩形
    ctx.save();  // 保存当前状态
    ctx.fillStyle = 'red';  // 改变填充颜色为红色
    ctx.fillRect(50, 50, 200, 100);  // 绘制红色矩形
    ctx.restore();  // 恢复之前保存的状态
    
    // 绘制第二个矩形
    ctx.save();  // 再次保存当前状态
    ctx.fillStyle = 'blue';  // 改变填充颜色为蓝色
    ctx.fillRect(100, 150, 200, 100);  // 绘制蓝色矩形
    ctx.restore();  // 恢复之前保存的状态

translate()

ctx.translate()(x, y),平移整个画布上的所有内容。

  • x, ynumber,水平、垂直方向的移动距离。

  • js
    // 绘制矩形
    ctx.fillStyle = 'blue';
    ctx.fillRect(50, 50, 100, 100); // 在 (50, 50) 位置绘制矩形
    
    // 使用 translate 平移坐标系
    ctx.translate(150, 0);  // 将原点平移 150 像素到右侧
    
    // 绘制另一个矩形
    ctx.fillStyle = 'red';
    ctx.fillRect(50, 50, 100, 100); // 此时矩形会绘制到 (200, 50) 位置

rotate()

ctx.rotate()(angle),用于旋转绘图上下文的坐标系。所有后续绘制的内容都将基于旋转后的坐标系进行。

  • angle弧度,旋转的弧度。公式: degree * Math.PI / 180 。可以通过 translate() 方法改变中心点。

  • js
    // 绘制矩形
    ctx.fillStyle = 'green';
    ctx.fillRect(50, 50, 100, 100);
    
    // 旋转坐标系 45 度(π/4 弧度)
    ctx.rotate(45 * Math.PI / 180);  // 旋转 45 度
    
    // 绘制矩形,旋转后的矩形
    ctx.fillStyle = 'blue';
    ctx.fillRect(50, 50, 100, 100);  // 绘制位置会旋转

scale()

ctx.scale()(x, y),用于缩放绘图上下文的整个坐标系。用来增减图形在canvas中的像素数目。会影响到所有后续绘制的图形。

  • x, ynumber,水平、垂直方向的缩放因子。大于1表示放大,小于1表示缩小,支持负数。

  • js
    // 绘制未缩放的矩形
    ctx.fillStyle = 'green';
    ctx.fillRect(50, 50, 100, 100);
    
    // 使用 scale 进行缩放
    ctx.scale(2, 1);  // 水平放大 2 倍,垂直方向保持不变
    
    // 绘制缩放后的矩形
    ctx.fillStyle = 'blue';
    ctx.fillRect(50, 50, 100, 100);  // 水平方向放大,垂直方向不变,矩形宽200,高100

动画

setInterval()

setInterval()(callback, interval?, arg1?, arg2?, ...),按照指定的时间间隔重复执行一个函数,直到被清除或页面关闭。

  • callback(arg1?, arg2?, ...) => void,要执行的回调函数。

  • interval?ms,时间间隔。

  • arg1?, arg2?, ...any,传递给回调函数的参数。

  • 返回:

  • intervalIdnumber,返回一个interval ID,可以调用clearInterval(intervalId)清除定时器。

  • js
    function greet(name) {
        console.log("Hello, " + name);
    }
    
    const intervalId = setInterval(greet, 2000, "Alice");

setTimeout()

setTimeout()(callback, delay, arg1, arg2, ...),在指定的延迟时间后执行一个函数,只执行一次。

  • callback(arg1?, arg2?, ...) => void,要执行的回调函数。

  • delayms,延迟时间。

  • arg1, arg2, ...any,传递给回调函数的参数。

  • 返回:

  • timeoutIdnumber,返回一个定时器 ID,可以调用clearTimeout(timeoutId)清除定时器。

  • js
    const timeoutId = setTimeout(function() {
        console.log("This will not be logged");
    }, 5000);
    
    // 在 2 秒后清除定时器
    setTimeout(function() {
        clearTimeout(timeoutId); // 清除定时器
        console.log("Timeout cleared before it executed.");
    }, 2000);

requestAnimationFrame()

requestAnimationFrame()(callback),一种浏览器提供的机制,用于在浏览器的下一次重绘之前执行一个函数,它被广泛应用于动画的实现。

  • callback(timestamp?) => void,当浏览器准备好绘制下一帧时执行。

    • timestamp?ms,表示调用时的时间戳。可用于计算动画的进度
  • 注意: 它能够与浏览器的渲染帧同步,减少不必要的重绘,从而提高性能。动画过渡平滑

  • 注意: 当页面被切换到后台时,requestAnimationFrame() 会暂停动画的执行,从而节省资源

  • 返回:

  • idnumber,返回一个整数 ID,该 ID 可以传递给 cancelAnimationFrame() 来取消该帧的请求。

  • js
    /** 让一个矩形在屏幕上移动 */
    var x = 50;
    var y = 50;
    var dx = 2;
    var dy = 2;
    
    function animate() {
        ctx.clearRect(0, 0, canvas.width, canvas.height); // 清除画布
        ctx.fillStyle = 'green';
        ctx.fillRect(x, y, 50, 50); // 绘制矩形
    
        x += dx; // 更新 x 坐标
        y += dy; // 更新 y 坐标
    
        // 如果矩形到达边缘,改变运动方向
        if (x + 50 > canvas.width || x < 0) {
            dx = -dx;
        }
        if (y + 50 > canvas.height || y < 0) {
            dy = -dy;
        }
    
        requestAnimationFrame(animate); // 请求下一帧
    }
    animate(); // 启动动画